package com.zxd.interview.conrruentbook;

import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.stream.IntStream;

/**
 * 屏障 测试
 * 案例：
 * 模拟不同任务提交订单、扣减库存、生成物流单
 */
public class CyclicBarrierTest {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {
            System.out.println("当前提交订单、扣减库存、生成物流单完毕");
        });
        // 三者可以同时进行
        new Thread(new CyclicBarrierTask("提交订单", cyclicBarrier)).start();
        new Thread(new CyclicBarrierTask("扣减库存", cyclicBarrier)).start();
        new Thread(new CyclicBarrierTask("生成物流单", cyclicBarrier)).start();
    }/**运行结果：

     任务1--完成提交订单的操作
     任务1--完成扣减库存的操作
     任务1--完成生成物流单的操作
     当前提交订单、扣减库存、生成物流单完毕

     任务2--完成提交订单的操作
     任务2--完成生成物流单的操作
     任务2--完成扣减库存的操作
     当前提交订单、扣减库存、生成物流单完毕
     
     任务3--完成生成物流单的操作
     任务3--完成扣减库存的操作
     任务3--完成提交订单的操作
     当前提交订单、扣减库存、生成物流单完毕
     Disconnected from the target VM, address: '127.0.0.1:9121', transport: 'socket'

     Process finished with exit code 0

     */

    private static class CyclicBarrierTask implements Runnable{
        private String task;
        private CyclicBarrier cyclicBarrier;

        public CyclicBarrierTask(String task, CyclicBarrier cyclicBarrier) {
            this.task = task;
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            // 1 2 3 和 for (i = 1; i <= 3; i++) 等价
            IntStream.rangeClosed(1, 3).forEach((i) -> {
                try {
                    Random random = new Random();
                    Thread.sleep(random.nextInt(2000));
                    System.out.println("任务" + i + "--完成" + task + "的操作");
                    // 阻塞等待
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //重置计数器的值
                cyclicBarrier.reset();
            });
        }
    }
}
